using System;
using BitBoard = System.UInt64;
//---------------------------------------------------------------------------//
//																			 //
//			r  n  C  h  e  s  s  B  o  a  r  d  C  o  n  t  r  o  l			 //
//			=======================================================			 //
//						  (c) 2003 Chris R. Chapman							 //
//																			 //
//	Version:		1.0	Full												 //
//  Date:			May 2003												 //
//  Author:			Chris R. Chapman (chris@chapmanconsulting.ca)			 //
//  Description:	A chessboard GUI written in 100% .Net/C#, featuring		 //
//					a resizable board with adjustable colors and configurable//
//					images for pieces, as well as events for capturing player//
//					movement and illegal moves.								 //
//																			 //
//																			 //
// LICENSING:		Can be freely distributed and used as long as the		 //
//					following criteria are met:								 //
//																			 //
//					1) All copyright notices are kept intact;				 //
//					2) Product is not for commercial resale;				 //
//					3) Product is NOT used in conjunction with ANY GPLed or  //
//					   FSF software.  I cannot abide by their philosophies.  //
//					4) Credit for the control to me is made in some			 //
//					   conspicuous fashion, like an About box.				 //
//---------------------------------------------------------------------------//
namespace RNChessRulesEngine
{
	/// <summary>
	/// Provides definitions of rotated bitboards for piece movement calculations
	/// </summary>
	public class RotatedBitBoard
	{

		/// <summary>
		/// Chessboard rotated 90 degrees to the left
		/// </summary>
		public static readonly int[] Right90 = new int[64]
			{
				56, 48, 40, 32, 24, 16,  8,  0, 
				57, 49, 41, 33, 25, 17,  9,  1, 
				58, 50, 42, 34, 26, 18, 10,  2, 
				59, 51, 43, 35, 27, 19, 11,  3, 
				60, 52, 44, 36, 28, 20, 12,  4, 
				61, 53, 45, 37, 29, 21, 13,  5, 
				62, 54, 46, 38, 30, 22, 14,  6, 
				63, 55, 47, 39, 31, 23, 15,  7 };


		/// <summary>
		/// Chessboard rotated 90 degrees to the right
		/// </summary>
		public static readonly int[] Left90 = new int[64]
			{
				7, 15, 23, 31, 39, 47, 55, 63, 
				6, 14, 22, 30, 38, 46, 54, 62, 
				5, 13, 21, 29, 37, 45, 53, 61, 
				4, 12, 20, 28, 36, 44, 52, 60, 
				3, 11, 19, 27, 35, 43, 51, 59, 
				2, 10, 18, 26, 34, 42, 50, 58, 
				1,  9, 17, 25, 33, 41, 49, 57, 
				0,  8, 16, 24, 32, 40, 48, 56 };
		

		/// <summary>
		/// Chessboard rotated towards upper left 45 degrees
		/// </summary>
		public static readonly int[] DiagA1H8Map = new int[64]
			{
				0,
				8,	 1,
				16,  9,  2,
				24, 17, 10,  3,
				32, 25, 18, 11,  4,
				40, 33, 26, 19, 12,  5,
				48, 41, 34, 27, 20, 13,  6,
				56, 49, 42, 35, 28, 21, 14,  7,
				57, 50, 43, 36, 29, 22, 15,
				58, 51, 44, 37, 30, 23,
				59, 52, 45, 38, 31,
				60, 53, 46, 39,
				61, 54, 47,
				62, 55,
				63 
			};


		/// <summary>
		/// Chessboard rotated 45 degrees toward upper right
		/// </summary>
		public static readonly int[] DiagA8H1Map = new int[64]
			{
				7, 
				6,	15, 
				5,	14, 23, 
				4,	13, 22, 31, 
				3,	12, 21, 30, 39, 
				2,	11, 20, 29, 38, 47, 
				1,	10, 19, 28, 37, 46, 55, 
				0,	9,	18, 27, 36, 45, 54, 63, 
				8,	17, 26, 35, 44, 53, 62, 
				16, 25, 34, 43, 52, 61, 
				24, 33, 42, 51, 60, 
				32, 41, 50, 59, 
				40, 49, 58, 
				48, 57, 
				56 
			};


		/// <summary>
		/// Chessboard rotated 45 degrees to the right
		/// </summary>
		public static readonly int[] Left45 = new int[64]
			{
				28, 21, 15, 10,  6,  3,  1, 0,
				36, 29,	22, 16, 11,  7,  4, 2, 
				43, 37, 30, 23, 17,	12,  8, 5, 
				49, 44, 38, 31,	24, 18, 13, 9, 
				54, 50, 45,	39, 32, 25, 19, 14, 
				58, 55, 51,	46, 40, 33, 26, 20,
				61, 59, 56, 52, 47, 41,	34, 27, 
				63, 62, 60, 57, 53,	48, 42,	35  
			};


		/// <summary>
		/// Chessboard rotated left 45 degrees
		/// </summary>
		public static readonly int[] Right45 = new int[64]
			{
				0,
				2,  5,
				9, 14, 20,
				27, 35,  1,  4,
				8, 13, 19, 26, 34,
				42,  3,  7, 12, 18, 25,
				33, 41, 48,  6, 11, 17, 24,
				32, 40, 47, 53, 10, 16, 23, 31,
				39, 46, 52, 57, 15, 22, 30,
				38, 45, 51, 56, 60, 21,
				29, 37, 44, 50, 55,
				59, 62, 28, 36,
				43, 49, 54,
				58, 61,
				63  
			};


		/// <summary>
		/// Lengths of A8 to H1 diagonals for each square
		/// </summary>
		public static readonly int[] DiagonalLengthA8H1 = new int[64]
			{
				8,7,6,5,4,3,2,1,
				7,8,7,6,5,4,3,2,
				6,7,8,7,6,5,4,3,
				5,6,7,8,7,6,5,4,
				4,5,6,7,8,7,6,5,
				3,4,5,6,7,8,7,6,
				2,3,4,5,6,7,8,7,
				1,2,3,4,5,6,7,8
			};
		

		/// <summary>
		/// Lengths of H1 to A8 diagonals for each square	
		/// </summary>
		public static readonly int[] DiagonalLengthA1H8 = new int[64]
			{
				1,2,3,4,5,6,7,8,
				2,3,4,5,6,7,8,7,
				3,4,5,6,7,8,7,6,
				4,5,6,7,8,7,6,5,
				5,6,7,8,7,6,5,4,
				6,7,8,7,6,5,4,3,
				7,8,7,6,5,4,3,2,
				8,7,6,5,4,3,2,1
			};


		/// <summary>
		/// Lookup table for bitshifting squares along the A8-H1 diagonal into the
		/// eight least significant bits
		/// </summary>
		public static readonly int[] DiagonalShiftA8H1 = new int[64]
			{
				28,21,15,10,6,3,1,0,
				36,28,21,15,10,6,3,1,
				43,36,28,21,15,10,6,3,
				49,43,36,28,21,15,10,6,
				54,49,43,36,28,21,15,10,
				58,54,49,43,36,28,21,15,
				61,58,54,49,43,36,28,21,
				63,61,58,54,49,43,36,28
			};
		

		/// <summary>
		/// Lookup table for bitshifting squares along the A1-H8 diagonal into the
		/// eight least significant bits
		/// </summary>
		public static readonly int[] DiagonalShiftA1H8 = new int[64]
			{
				0,1,3,6,10,15,21,28,
				1,3,6,10,15,21,28,36,
				3,6,10,15,21,28,36,43,
				6,10,15,21,28,36,43,49,
				10,15,21,28,36,43,49,54,
				15,21,28,36,43,49,54,58,
				21,28,36,43,49,54,58,61,
				28,36,43,49,54,58,61,63
			};

		/// <summary>
		/// Chessboard with diagonal lengths for each position
		/// </summary>
		public static readonly int[] DiagonalLength = new int[64]
			{
				1,
				2,  2,
				3,  3,  3,
				4,  4,  4,  4,
				5,  5,  5,  5,  5,
				6,  6,  6,  6,  6,  6,
				7,  7,  7,  7,  7,  7,  7,
				8,  8,  8,  8,  8,  8,  8,  8,
				7,  7,  7,  7,  7,  7,  7,
				6,  6,  6,  6,  6,  6,
				5,  5,  5,  5,  5,
				4,  4,  4,  4,
				3,  3,  3,
				2,  2,
				1 
			};
	

		/// <summary>
		/// Chessboard with diagonal square positions
		/// </summary>
		public static readonly int[] DiagonalSquares = new int[64]
			{
							0,
						  1,  0, 
						2,  1,  0, 
					  3,  2,  1,  0, 
				    4,  3,  2,  1,  0, 
				  5,  4,  3,  2,  1,  0, 
				6,  5,  4,  3,  2,  1,  0,	
			  7,  6,  5,  4,  3,  2,  1,  0,
			    6,  5,  4,  3,  2,  1,  0, 
				  5,  4,  3,  2,  1,  0,  
					4,  3,  2,  1,  0,  
					  3,  2,  1,  0, 
						2,  1,  0, 
						  1,  0, 
							0 
			};

		/// <summary>
		/// Lookup index for finding the number of bits a given rank
		/// needs to be shifted to the least 8 significant bits of a
		/// bitboard.
		/// </summary>
		public static readonly int[] ShiftBitsIndex = new int[64]
			{
				0,0,0,0,0,0,0,0,
				8,8,8,8,8,8,8,8,
				16,16,16,16,16,16,16,16,
				24,24,24,24,24,24,24,24,
				32,32,32,32,32,32,32,32,
				40,40,40,40,40,40,40,40,
				48,48,48,48,48,48,48,48,
				56,56,56,56,56,56,56,56
			};


		/// <summary>
		/// BitBoard Mask for 90 degree left rotated bitboard
		/// </summary>
		public static readonly BitBoard[] RotateLeft90Mask = new BitBoard[64];


		/// <summary>
		/// BitBoard Mask for 45 degree left rotated bitboard
		/// </summary>
		public static readonly BitBoard[] RotateLeft45Mask = new BitBoard[64];

		
		/// <summary>
		/// BitBoard mask for 45 degree right rotated bitboard
		/// </summary>
		public static readonly BitBoard[] RotateRight45Mask = new BitBoard[64];

		/// <summary>
		/// Instantiates the RotatedBitBoard object.
		/// </summary>
		public RotatedBitBoard()
		{
			InitializeRotatedBitBoardMasks();
		}


		/// <summary>
		/// Constructs the rotated bitboard masks for left 90, right 45 and left 45
		/// </summary>
		private void InitializeRotatedBitBoardMasks()
		{
			BitBoard bit = 1;
			BitBoard shiftedBit;
			for(int square=0; square < 64; square++)
			{
				shiftedBit = (bit << square);
				RotateLeft90Mask[square] = shiftedBit >> Right90[square];
				RotateRight45Mask[square] = shiftedBit >> Right45[square];
				RotateLeft45Mask[square] = shiftedBit >> Left45[square];
			}
		}

	}
}
